﻿using System.Diagnostics;
using System.IO;
using System.Linq;

using Microsoft.Coding4Fun.TweetCraft.Wow;
using Moq;
using NUnit.Framework;

namespace Microsoft.Coding4Fun.TweetCraft.Tests
{
    [TestFixture]
    public class WorldOfWarcraftTest
    {
        private const string wowTestDirectory = "World of Warcraft";

        private IWorldOfWarcraft worldOfWarcraft;

        [SetUp]
        public void SetUp()
        {
            // Initialize a World of Warcraft instance that detects WoW in the test directory
            var worldOfWarcraftMock = new Mock<WorldOfWarcraft>();

            // Set up the instance to return the absolute path to the 'World of Warcraft' directory
            worldOfWarcraftMock.Setup(wow => wow.InstallPath)
                .Returns(Path.GetFullPath(wowTestDirectory));

            // Assign the mock object
            worldOfWarcraft = worldOfWarcraftMock.Object;

            // Assert that a World of Warcraft installation is detected
            Assert.IsTrue(worldOfWarcraft.IsDetected);
        }

        [Test]
        public void GetAccountNamesTest()
        {
            string[] accountNames = worldOfWarcraft.GetAccountNames();

            // Assert that the array holding the account names is not null and contains at least one account
            Assert.IsNotNull(accountNames);
            Assert.IsTrue(accountNames.Length > 0);

            WriteNames("Accounts", accountNames);
        }

        [Test]
        public void GetAddOnNamesTest()
        {
            string[] addOnNames = worldOfWarcraft.GetAddOnNames();

            // Assert that the array holding the account names is not null and contains at least one addon
            Assert.IsNotNull(addOnNames);
            Assert.IsTrue(addOnNames.Length > 0);

            WriteNames("AddOns", addOnNames);
        }

        [Test]
        public void GetAddOnPathTest()
        {
            // Get the first addon name in World of Warcraft
            string addOnName = worldOfWarcraft.GetAddOnNames().First();

            // Get the path to the addon
            string addOnPath = worldOfWarcraft.GetAddOnPath(addOnName);

            // Assert that the path is not null
            Assert.IsNotNull(addOnPath);
        }

        [Test]
        public void IsAddOnInstalledTest()
        {
            // Get the first addon name in World of Warcraft
            string addOnName = worldOfWarcraft.GetAddOnNames().First();

            // Assert that the addon is detected as installed
            Assert.IsTrue(worldOfWarcraft.IsAddOnInstalled(addOnName));
        }

        [Test]
        public void GetAddOnVersionTest()
        {
            // Get the first addon name in World of Warcraft
            string addOnName = worldOfWarcraft.GetAddOnNames().First();

            // Assert that the version of the addon can be retrieved
            Assert.IsNotNull(worldOfWarcraft.GetAddOnVersion(addOnName));           
        }

        [Test]
        public void IsNotInstalledAddOnInstalledTest()
        {
            // Assert that no addon is installed with the name 'bogus'
            Assert.IsFalse(worldOfWarcraft.IsAddOnInstalled("bogus"));
        }

        [Test]
        public void GetRealmNamesTest()
        {
            // Get the first account name in World of Warcraft
            string accountName = worldOfWarcraft.GetAccountNames().First();

            // Get the name of realms for an account
            string[] realmNames = worldOfWarcraft.GetRealmNames(accountName);

            // Assert that the array holding the realm names is not null and contains at least one realm
            Assert.IsNotNull(realmNames);
            Assert.IsTrue(realmNames.Length > 0);

            WriteNames("Realms", realmNames);
        }

        [Test]
        public void GetCharacterNamesTest()
        {
            // Get the first account and realm name in World of Warcraft
            string accountName = worldOfWarcraft.GetAccountNames().First();
            string realmName = worldOfWarcraft.GetRealmNames(accountName).First();

            string[] characterNames = worldOfWarcraft.GetCharacterNames(accountName, realmName);

            // Assert that the array holding the realm names is not null and contains at least one realm
            Assert.IsNotNull(characterNames);
            Assert.IsTrue(characterNames.Length > 0);

            WriteNames("Characters", characterNames);
        }
        [Test]
        public void GetSavedVariablesPathTest()
        {
            // Get the first account name in World of Warcraft
            string accountName = worldOfWarcraft.GetAccountNames().First();

            // Get the path to the SavedVariables file used by the 'TweetCraft' addon
            string savedVariablesPath = worldOfWarcraft.GetSavedVariablesPath(accountName, "TweetCraft");

            // Assert that a path was returned
            Assert.IsNotNull(savedVariablesPath);
        }

        [Test]
        public void GetSavedVariablesPerCharacterPathTest()
        {
            // Get the first account, realm and character name in World of Warcraft
            string accountName = worldOfWarcraft.GetAccountNames().First();
            string realmName = worldOfWarcraft.GetRealmNames(accountName).First();
            string characterName = worldOfWarcraft.GetCharacterNames(accountName, realmName).First();

            // Get the path to the SavedVariables file used by the 'TweetCraft' addon
            string savedVariablesPath = worldOfWarcraft.GetSavedVariablesPerCharacterPath(accountName, realmName, characterName, "TweetCraft");

            // Assert that a path was returned
            Assert.IsNotNull(savedVariablesPath);
        }

        private static void WriteNames(string caption, string[] names)
        {
            Trace.WriteLine(caption + ": ");
            foreach (string name in names)
                Trace.WriteLine(" - " + name);
        }
    }
}
